import os
import random
import re
import sys

from django.http import HttpResponse, HttpResponseForbidden
from django.views import View
from django_redis import get_redis_connection
from rest_framework.response import Response
from rest_framework.views import APIView
from rest_framework.permissions import AllowAny

from libs.captcha.captcha import captcha
from libs.rl_sms import send_message


class ImageCodeView(View):
    def get(self, request):
        """
        请求获取图片接口, 是普通类视图, 需要一个uuid参数, 用来关联图片
        :param request:
        :return:
        """
        # 1, 接收数据
        uuid = request.GET.get('uuid')
        print("uuid%s"%uuid)

        # 2, 校验数据
        if not uuid:
            return HttpResponseForbidden('uuid无效')

        # 3, 处理业务
        # 获取图片文本内容和图片二进制代码
        text, image = captcha.generate_captcha()

        # 把uuid和图片文本存入redis
        # 获取redis客户端,
        redis_client = get_redis_connection('verify_code')
        # 写入redis
        redis_client.setex(uuid, 60 * 5, text)

        # 4, 返回响应
        return HttpResponse(image, content_type='image/jpg')


# class SmsCodeView(APIView):
#     # 1. 所有人可以访问
#     permission_classes = (AllowAny,)
#
#     def post(self, request):
#         # 1. 获取参数
#         phone = request.data.get('phone')
#         image_code = request.data.get('image_code')
#         image_code_uuid = request.data.get('image_code_uuid')
#         print("image_code_uuid,%s"%image_code_uuid)
#
#         # 2. 检查参数
#         if not all([phone, image_code, image_code_uuid]):
#             return Response({"code": 999, "msg": "参数不全"})
#         if not re.match(r'^1[3456789]\d{9}$', phone):
#             return Response({"code": 999, "msg": "手机号码不正确"})
#
#         # 3. 检查是否发送
#         redis_client = get_redis_connection('verify_code')
#         phone_exists = redis_client.get(phone)
#         if phone_exists:
#             return Response({"code": 999, "msg": "频繁发送, 请稍后再试"})
#
#         redis_image_code = redis_client.get(image_code_uuid)  # bytes
#         if redis_image_code:
#             # bytes 转成 string
#             redis_image_code = redis_image_code.decode()
#
#         # 比较用户提供的图片内容是否和redis中保存的一致
#         if image_code.upper() != redis_image_code:
#             return Response({'code': 999, 'msg': '图片验证码不正确'})
#
#         # 4. 发送
#         code = '%06d' % random.randint(0, 999999)  # 随机6位验证码
#         send_resp = send_message(phone, (code, "5"))
#         print(send_resp)
#         if send_resp=="-1":
#             return Response({"code": 400, "msg": "短信发送失败"})
#
#         # 5.1 保存code 到 redis中
#         # redis_client.setex(phone, 60 * 5, code)  # phone:code, 5分钟有效期
#
#         # 5.2 从redis中删除这个图片验证码, 以防再次被使用
#         # redis_client.delete(image_code_uuid)
#
#         # 5.3 使用 pipeline 批量操作
#         pl = redis_client.pipeline()
#         pl.setex(phone, 60 * 5, code)
#         pl.delete(image_code_uuid)
#         pl.execute()
#
#         # 6. 返回结果
#         return Response({"code": 0, "msg": "短信发送成功"})

class SMS_code(APIView):
    permission_classes=(AllowAny,)
    #允许所有用户访问，但是有访问次数
    def post(self,request):
        '''
        :param request: 传递手机号，图片验证码，图片的uuid身份信息，1，首先检查所有参数是否齐全2，检查手机号的验证码是否已保存，已保存说明已发送短息，3，检查验证码是否匹配，（验证码的获取需要把redis的数据转为字符串，判断是否为空，不为空了才可以转）4，生成并发送手机验证码，并且检查发送的结果，看是否获取参数或者参数为空，就是发送失败
        :return: 返回各个环节的错误 或者发送成功的信息
        '''
        phone = request.data.get("phone")
        img_code = request.data.get("image_code")
        img_uuid = request.data.get("image_code_uuid")

        if not all([phone,img_code,img_uuid]):
            return Response({"code":400,"msg":"参数不全"})
        if not re.match(r'^1[23456789]\d{9}$',phone):
            return Response({"code":400,"msg":"手机号格式错误"})
        redis_cli = get_redis_connection("verify_code")  #与django_redis建立连接
        # phone_code = redis_cli.get(phone)
        # if phone_code:
        #     return Response({"code":400,"msg":"信息已发送，请稍后再试"})
        redis_img_code = redis_cli.get(img_uuid)
        if redis_img_code:
            redis_img_code = redis_img_code.decode()
        if img_code.upper() != redis_img_code:
            return Response({"code":400,"msg":"验证码输入错误"})
        code = "%06d"%random.randint(0,999999)
        print(code)
        # from syl.settings import BASE_DIR
        # sys.path.insert(0,os.path.join(BASE_DIR,"../celery_task"))
        from main import send_sms_code #必须这么写，从main中导包
        # send_sms_code.delay(phone,(code,"5"))


        # send_phone = send_message(phone,(code,3))
        # if send_phone == "-1":
        #     return Response({"code":400,"msg":"验证码发送失败"})
        #5,使用pipline执行，与数据库的连接较少，性能得到提高
        pl = redis_cli.pipeline()
        pl.setex(phone,60*5,code)
        pl.delete(img_uuid)
        pl.execute()
        return Response({"code": 200, "msg": "验证码发送成功"})




